package com.hitqz.robot.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hitqz.robot.api.business.model.param.patrol.QueryPatrolPoseGroupPageParams;
import com.hitqz.robot.api.business.model.vo.patrol.PatrolPoseVo;
import com.hitqz.robot.api.common.entity.*;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.camera.EquipmentFactory;
import com.hitqz.robot.camera.IEquipmentService;
import com.hitqz.robot.camera.dto.EquipmentParamsDto;
import com.hitqz.robot.camera.dto.QueryParamsDto;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author wengyx
 * @date 2024/8/7
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/patrolPoseGroup")
@Tag(name = "巡检姿态组管理")
public class PatrolPoseGroupController {

    private final PatrolPoseGroupService patrolPoseGroupService;

    private final PatrolPosPoseGroupService patrolPosPoseGroupService;

    private final PatrolDevService patrolDevService;

    private final PatrolPoseService patrolPoseService;

    private final RobotEquipmentService robotEquipmentService;

    private final EquipmentFactory equipmentFactory;

    @PostMapping("/page")
    @Operation(summary = "分页查询姿态组列表")
    public R<Page<PatrolPoseGroup>> page(@RequestBody QueryPatrolPoseGroupPageParams queryPageParams) {
        Page page = new Page<>(queryPageParams.getCurrent(),queryPageParams.getSize());
        Page<PatrolPoseGroup> data = patrolPoseGroupService.page(page,
                Wrappers.<PatrolPoseGroup>lambdaQuery()
                        .like(StrUtil.isNotBlank(queryPageParams.getName()),PatrolPoseGroup::getName,queryPageParams.getName()));
        return R.ok(data);
    }


    @PostMapping("/list")
    @Operation(summary = "获取巡检姿态组列表")
    public R<List<PatrolPoseGroup>> list() {
        List<PatrolPoseGroup> data = patrolPoseGroupService.list();
        //按id倒序
        data.sort((o1, o2) -> o2.getId().compareTo(o1.getId()));
        return R.ok(data);
    }

    @GetMapping("/{id}" )
    @Operation(summary = "根据id查询巡检姿态组")
    public R<PatrolPoseGroup> getById(@PathVariable("id") Integer id) {
        PatrolPoseGroup patrolPoseGroup = patrolPoseGroupService.getById(id);
        return R.ok(patrolPoseGroup);
    }

    @GetMapping("/{id}/patrolPose" )
    @Operation(summary = "根据id查询巡检姿态组下姿态")
    public R<List<PatrolPoseVo>> getPoseVoListById(@PathVariable("id") Integer id) {
        List<PatrolPose> poseList = patrolPoseService.list(Wrappers.<PatrolPose>lambdaQuery().eq(PatrolPose::getGroupId, id));
        List<PatrolPoseVo> voList = BeanUtil.copyToList(poseList, PatrolPoseVo.class);
        return R.ok(voList);
    }


    @PostMapping
    @Operation(summary = "新增巡检姿态组")
    public R save(@RequestBody(required = false) PatrolPoseGroup dto) {
        if(dto == null){
            dto = new PatrolPoseGroup();
        }
        boolean result = patrolPoseGroupService.save(dto);
        if (StrUtil.isBlank(dto.getName())){
            dto.setName("姿态组_"+dto.getId());
            boolean update = patrolPoseGroupService.updateById(dto);
        }
        List<RobotEquipment> list = robotEquipmentService.list(Wrappers.<RobotEquipment>lambdaQuery().eq(RobotEquipment::getIsRecordParam, 1));
        //todo 
        List<PatrolPose> patrolPoses = new ArrayList<>();
        try {
            for (RobotEquipment equipment : CollUtil.emptyIfNull(list)) {
                List<EquipmentParamsDto> equipmentParamsDtos = robotEquipmentService.getEquipmentParams(equipment);
                if (CollUtil.isNotEmpty(equipmentParamsDtos)) {
                    PatrolPose pose = new PatrolPose();
                    pose.setGroupId(dto.getId().intValue());
                    pose.setEquipmentId(equipment.getId().intValue());
                    pose.setJson(JSON.toJSONString(equipmentParamsDtos));
                    patrolPoses.add(pose);
                }
            }
        }catch (Exception e){
            log.error("获取外设参数失败", e);
            patrolPoseGroupService.removeById(dto);
            return R.failed("获取外设姿态失败,请检查外设是否正常");
        }
        if (!patrolPoses.isEmpty()) {
            patrolPoseService.saveBatch(patrolPoses);
        }
        return R.ok(dto.getId());
    }

    @PutMapping
    @Operation(summary = "修改巡检姿态组")
    public R updateById(@RequestBody @Validated PatrolPoseGroup dto) {
        return R.ok(patrolPoseGroupService.updateById(dto));
    }

    @DeleteMapping
    @Operation(summary = "根据id删除巡检姿态组")
    public R removeById(@RequestBody Integer[] ids) {
        return R.ok(patrolPoseGroupService.removeBatchByIds(CollUtil.toList(ids)));
    }

    @GetMapping("/{id}/updatePose" )
    @Operation(summary = "更新姿态组姿态")
    public R updatePose(@PathVariable("id") Integer id) {
        PatrolPoseGroup patrolPoseGroup = patrolPoseGroupService.getById(id);
        if (patrolPoseGroup==null){
            return R.failed("未找到姿态组信息");
        }
        List<RobotEquipment> list = robotEquipmentService.list(Wrappers.<RobotEquipment>lambdaQuery().eq(RobotEquipment::getIsRecordParam, 1));
        List<PatrolPose> patrolPoses = new ArrayList<>();
        try {
            for (RobotEquipment equipment : CollUtil.emptyIfNull(list)) {
                List<EquipmentParamsDto> equipmentParamsDtos = robotEquipmentService.getEquipmentParams(equipment);
                if (CollUtil.isNotEmpty(equipmentParamsDtos)) {
                    PatrolPose pose = new PatrolPose();
                    pose.setGroupId(patrolPoseGroup.getId().intValue());
                    pose.setEquipmentId(equipment.getId().intValue());
                    pose.setJson(JSON.toJSONString(equipmentParamsDtos));
                    patrolPoses.add(pose);
                }
            }
        }catch (Exception e){
            log.error("获取参数失败", e);
            return R.failed("获取外设姿态失败,请检查外设是否正常");
        }
        //删除旧的
        patrolPoseService.remove(Wrappers.<PatrolPose>lambdaQuery().eq(PatrolPose::getGroupId,patrolPoseGroup.getId()));
        //增加新的
        patrolPoseService.saveBatch(patrolPoses);
        return R.ok();
    }

    @GetMapping("/{id}/dev" )
    @Operation(summary = "查询绑定该姿态组的设备")
    public R<List<PatrolDev>> dev(@PathVariable("id") Integer id){
        List<PatrolPosPoseGroup> list = patrolPosPoseGroupService.list(Wrappers.<PatrolPosPoseGroup>lambdaQuery().eq(PatrolPosPoseGroup::getPatrolPoseGroupId, id));
        Set<Integer> devIds = new HashSet<>();
        for (PatrolPosPoseGroup patrolPosPoseGroup : CollUtil.emptyIfNull(list)) {
            devIds.add(patrolPosPoseGroup.getDevId());
        }
        if (devIds.isEmpty()){
            return R.ok();
        }else {
            List<PatrolDev> patrolDevs = patrolDevService.listByIds(devIds);
            return R.ok(patrolDevs);
        }
    }



    @GetMapping("/{id}/execute")
    @Operation(summary = "调用姿态组")
    public R execute(@PathVariable("id") Integer id,
                     @RequestParam(value = "cmd") @Parameter(description = "命令:0-回正 1-调用") Integer cmd) {
        try {
            List<PatrolPose> list = patrolPoseService.list(Wrappers.<PatrolPose>lambdaQuery().eq(PatrolPose::getGroupId, id));
            if (list.isEmpty()){
                return R.failed("姿态组下无姿态");
            }
            for (PatrolPose patrolPose : list) {
                R r = patrolPoseService.executeAsync(patrolPose, cmd);
                if (r.getCode()==R.failed().getCode()){
                    return r;
                }
            }
            return R.ok();
        }catch (Exception e){
            log.error("调用姿态失败",e);
            return R.failed("调用姿态失败");
        }
    }

}
